<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>The source code</title>
  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  <style type="text/css">
    .highlight { display: block; background-color: #ddd; }
  </style>
  <script type="text/javascript">
    function highlight() {
      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
    }
  </script>
</head>
<body onload="prettyPrint(); highlight();">
  <pre class="prettyprint lang-js"><span id='global-property-'>/**
</span> * @ignore
 * menu where items can be filtered based on user keyboard input
 * @author yiminghe@gmail.com
 */
KISSY.add(&quot;filter-menu&quot;, function (S, Menu, FilterMenuRender) {

    var HIT_CLS = &quot;menuitem-hit&quot;;

<span id='KISSY-FilterMenu'>    /**
</span>     * Filter Menu for KISSY.
     * xclass: 'filter-menu'.
     * @extends KISSY.Menu
     * @class KISSY.FilterMenu
     */
    return Menu.extend({
            bindUI: function () {
                var self = this,
                    filterInput = self.get(&quot;filterInput&quot;);
                /*监控键盘事件*/
                filterInput.on(&quot;valuechange&quot;, self.handleFilterEvent, self);
            },

            handleMouseEnterInternal: function (e) {
                var self = this;
                self.callSuper(e);
                // 权益解决,filter input focus 后会滚动到牌聚焦处,select 则不会
                // 如果 filtermenu 的菜单项被滚轮滚到后面,点击触发不了,会向前滚动到 filter input
                self.view.getKeyEventTarget()[0].select();
            },

            handleFilterEvent: function () {
                var self = this,
                    str,
                    filterInput = self.get(&quot;filterInput&quot;),
                    highlightedItem = self.get(&quot;highlightedItem&quot;);
                /* 根据用户输入过滤 */
                self.set(&quot;filterStr&quot;, filterInput.val());
                str = filterInput.val();
                if (self.get('allowMultiple')) {
                    str = str.replace(/^.+,/, '');
                }

                if (!str &amp;&amp; highlightedItem) {
                    highlightedItem.set('highlighted', false);
                }
                // 尽量保持原始高亮
                // 如果没有高亮项或者高亮项因为过滤被隐藏了
                // 默认选择符合条件的第一项
                else if (str &amp;&amp; (!highlightedItem || !highlightedItem.get(&quot;visible&quot;))) {
                    highlightedItem = self._getNextEnabledHighlighted(0, 1);
                    if (highlightedItem) {
                        highlightedItem.set('highlighted', true);
                    }
                }
            },

            '_onSetFilterStr': function (v) {
                // 过滤条件变了立即过滤
                this.filterItems(v);
            },

<span id='KISSY-FilterMenu-method-filterItems'>            /**
</span>             * Specify how to filter items.
             * @param {String} str User input.
             */
            filterItems: function (str) {
                var self = this,
                    prefixCls = self.get('prefixCls'),
                    _placeholderEl = self.get(&quot;placeholderEl&quot;),
                    filterInput = self.get(&quot;filterInput&quot;);

                // 有过滤条件提示隐藏,否则提示显示
                _placeholderEl[str ? &quot;hide&quot; : &quot;show&quot;]();

                if (self.get(&quot;allowMultiple&quot;)) {
                    var enteredItems = [],
                        lastWord;
                    // \uff0c =&gt; ，
                    var match = str.match(/(.+)[,\uff0c]\s*([^\uff0c,]*)/);
                    // 已经确认的项
                    // , 号之前的项必定确认

                    var items = [];

                    if (match) {
                        items = match[1].split(/[,\uff0c]/);
                    }

                    // 逗号结尾
                    // 如果可以补全,那么补全最后一项为第一个高亮项
                    if (/[,\uff0c]$/.test(str)) {
                        enteredItems = [];
                        if (match) {
                            enteredItems = items;
                            //待补全的项
                            lastWord = items[items.length - 1];
                            var item = self.get(&quot;highlightedItem&quot;),
                                content = item &amp;&amp; item.get(&quot;content&quot;);
                            // 有高亮而且最后一项不为空补全
                            if (content &amp;&amp; content.indexOf(lastWord) &gt; -1 &amp;&amp; lastWord) {
                                enteredItems[enteredItems.length - 1] = content;
                            }
                            filterInput.val(enteredItems.join(&quot;,&quot;) + &quot;,&quot;);
                        }
                        str = '';
                    } else {
                        // 需要菜单过滤的过滤词,在最后一个 , 后面
                        if (match) {
                            str = match[2] || &quot;&quot;;
                        }
                        // 没有 , 则就是当前输入的
                        // else{ str=str}

                        //记录下
                        enteredItems = items;
                    }
                    var oldEnteredItems = self.get(&quot;enteredItems&quot;);
                    // 发生变化,长度变化和内容变化等同
                    if (oldEnteredItems.length != enteredItems.length) {
                        // S.log(&quot;enteredItems : &quot;);
                        // S.log(enteredItems);
                        self.set(&quot;enteredItems&quot;, enteredItems);
                    }
                }

                var children = self.get(&quot;children&quot;),
                    strExp = str &amp;&amp; new RegExp(S.escapeRegExp(str), &quot;ig&quot;);

                // 过滤所有子组件
                S.each(children, function (c) {
                    var content = c.get(&quot;content&quot;);
                    if (!str) {
                        // 没有过滤条件
                        // 恢复原有内容
                        // 显示出来
                        c.get('el').html(content);
                        c.set(&quot;visible&quot;, true);
                    } else {
                        if (content.indexOf(str) &gt; -1) {
                            // 如果符合过滤项
                            // 显示
                            c.set(&quot;visible&quot;, true);
                            // 匹配子串着重 input-wrap
                            c.get('el').html(content.replace(strExp, function (m) {
                                return &quot;&lt;span class='&quot; + prefixCls + HIT_CLS + &quot;'&gt;&quot; + m + &quot;&lt;&quot; + &quot;/span&gt;&quot;;
                            }));
                        } else {
                            // 不符合
                            // 隐藏
                            c.set(&quot;visible&quot;, false);
                        }
                    }
                });
            },

<span id='KISSY-FilterMenu-method-reset'>            /**
</span>             * Reset user input.
             */
            reset: function () {
                var self = this;
                self.set(&quot;filterStr&quot;, &quot;&quot;);
                self.set(&quot;enteredItems&quot;, []);
                self.get(&quot;filterInput&quot;).val(&quot;&quot;);
            }

        },
        {
            ATTRS: {
                allowTextSelection: {
                    value: true
                },

<span id='KISSY-FilterMenu-cfg-placeholder'>                /**
</span>                 * Hit info string
                 * @cfg {String} placeholder
                 */
<span id='global-property-placeholder'>                /**
</span>                 * @ignore
                 */
                placeholder: {
                    view: 1
                },

<span id='KISSY-FilterMenu-cfg-filterStr'>                /**
</span>                 * Filter string
                 * @cfg {String} filterStr
                 */
<span id='global-property-filterStr'>                /**
</span>                 * @ignore
                 */
                filterStr: {
                },

<span id='global-property-enteredItems'>                /**
</span>                 * user entered string list when allowMultiple.
                 * @type {String[]}
                 * @ignore
                 */
                enteredItems: {
                    value: []
                },

<span id='KISSY-FilterMenu-cfg-allowMultiple'>                /**
</span>                 * Whether to allow input multiple.
                 * @cfg {Boolean} allowMultiple
                 */
<span id='global-property-allowMultiple'>                /**
</span>                 * @ignore
                 */
                allowMultiple: {
                    value: false
                },

                xrender: {
                    value: FilterMenuRender
                }
            },
            xclass: 'filter-menu'
        });
}, {
    requires: ['menu', 'filter-menu/render']
});</pre>
</body>
</html>
